package com.mf.controller.theLock;

import com.mf.result.Result;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @Author: lmf
 * @Create: 2025/5/15 20:06
 * @module 锁
 */
@RestController
@RequestMapping("/theLock")
public class TheLock {

    @Operation(summary = "synchronized锁的范围")
    @GetMapping("synchronizedScoped")
    public Result<String> synchronizedScoped() {
        // 锁的范围是整个类
        MyLock.a();
        final MyLock myLock = new MyLock();
        // 锁的范围new出来的myLock对象
        myLock.b();
        ReentrantLock reentrantLock = new ReentrantLock();
        reentrantLock.lock();
        return Result.success();
    }

    @Operation(summary = "ConditionObject使用（lock锁实现await）")
    @GetMapping("conditionObject")
    public Result<Void> conditionObject() throws InterruptedException {
        ReentrantLock lock = new ReentrantLock();
        Condition condition = lock.newCondition();

        new Thread(() -> {
            lock.lock();
            System.out.println("子线程获取锁资源并await挂起线程");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("子线程挂起后被唤醒！持有锁资源");

        }).start();
        Thread.sleep(100);
        // =================main======================
        lock.lock();
        System.out.println("主线程等待5s拿到锁资源，子线程执行了await方法");
        condition.signal();
        System.out.println("主线程唤醒了await挂起的子线程");
        lock.unlock();
        return Result.success();
    }

    // 读写锁
    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    // 读锁
    private ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
    // 写锁
    private ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();

    @Operation(summary = "读写锁ReentrantReadWriteLock-读读操作")
    @GetMapping("reentrantReadWriteLock_read")
    public Result<Void> reentrantReadWriteLock() {
        new Thread(() -> {
            readLock.lock();
            System.out.println("子线程");
            try {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            } finally {
                readLock.unlock();
            }
        }).start();


        try {
            Thread.sleep(100);
            readLock.lock();
            System.out.println("主线程读读之间不需要等待");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            readLock.unlock();
        }
        return Result.success();
    }

    @Operation(summary = "ReentrantReadWriteLock读写锁，读写互斥")
    @GetMapping("reentrantReadWriteLock_write")
    public Result<Void> reentrantReadWriteLock_write() throws InterruptedException {
        new Thread(() -> {
            writeLock.lock();
            System.out.println("子线程开始写。。。");
            try {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            } finally {
                writeLock.unlock();
                System.out.println("子线程完成写");
            }
        }).start();

        try {
            Thread.sleep(100);
            readLock.lock();
            System.out.println("等待子线程写完才会执行");
        } finally {
            readLock.unlock();
            System.out.println("主线程读完");
        }

        return Result.success();
    }


}
